package com.mantou.proxyservice.utils;

import java.io.IOException;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;

import org.apache.commons.io.IOUtils;
import org.apache.http.HttpHost;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.mantou.cdl.net.HttpInvoker;
import com.mantou.cdl.net.HttpResult;
import com.mantou.proxyadapter.importer.DefaultImporter;
import com.mantou.proxyadapter.pool.Proxy;




/**
 * ClassName:ProxyUtil
 * 
 * @see
 * @author ch
 * @version Ver 1.0
 * @Date 2014-2-16 下午04:20:07
 */
public class ProxyUtil {
	// TODO 改为单例
	public final static String testkey ="if a client get this string,we think proxy is realy avaible. qq group 428174328";
	private static final String keysourceurl = "http://123.56.155.209/proxyservice/system/key";
	//private static final String keysourceurl = "http://127.0.0.1/proxyservice/system/key";
	private static InetAddress localAddr;
	private static final Logger logger = LoggerFactory.getLogger(ProxyUtil.class);
	static {
		init();
	}

	public static void main(String args[]) throws  Exception{
		/*System.out.println("localAddr"+localAddr);//new HttpHost(InetAddress.getByName(s[0]), Integer.valueOf(s[1]))"61.178.248.165", 55336
		System.out.println("61.178.248.165"+validateProxy(new HttpHost(InetAddress.getByName("61.178.248.165"),55336)));

		System.out.println("188.226.195.234"+validateProxy(new HttpHost(InetAddress.getByName("188.226.195.234"),80)));

		//System.out.println("171.9.220.1"+validateProxy(new HttpHost(InetAddress.getByName("171.9.220.1"),80)));

		System.out.println("119.167.197.89"+validateProxy(new HttpHost(InetAddress.getByName("119.167.197.89"),55336)));
		System.out.println("218.60.101.1.36"+validateProxy(new HttpHost(InetAddress.getByName("218.60.101.1.36"),55336)));*/
		DefaultImporter importer = new DefaultImporter();
		final AtomicLong counter = new AtomicLong(0);
		List<Proxy> newproxys = importer.newproxy(1024);
		List<Thread> threads = new ArrayList<Thread>();
		for(final Proxy proxy:newproxys){


			Thread thread = new Thread(){

				@Override
				public void run() {
					// TODO Auto-generated method stub
					super.run();
					try {
						HttpResult request = new HttpInvoker("http://news.rugao35.com/newsshow-144387.html").setproxy(proxy.getIp(), proxy.getPort()).request();
						if(request!=null){
							System.out.println(request.getStatusCode()+""+IOUtils.toString(request.getResponseBody()));
							if(request.getStatusCode() == 200){
								counter.addAndGet(1);
							}
						}
					} catch (Exception e) {
						// TODO Auto-generated catch block
						System.out.println(e.getMessage());
					}
				}

			};
			thread.start();
			threads.add(thread);
		}

		for(Thread thread:threads){
			thread.join();
		}
		System.out.println("num:"+counter.get());
	}

	private static void init() {
		Enumeration<InetAddress> localAddrs;
		try {
			Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
			/*NetworkInterface ni = NetworkInterface.getByName("eth7");
			if (ni == null) {
				logger.error("choose NetworkInterface\n" + getNetworkInterface());
			}*/
			while(networkInterfaces.hasMoreElements()){
				NetworkInterface ni = networkInterfaces.nextElement();
				localAddrs = ni.getInetAddresses();
				while (localAddrs.hasMoreElements()) {
					InetAddress tmp = localAddrs.nextElement();
					if (!tmp.isLoopbackAddress() && !tmp.isLinkLocalAddress() && !(tmp instanceof Inet6Address)) {
						localAddr = tmp;
						logger.info("local IP:" + localAddr.getHostAddress());
						return;
					}
				}
			}

		} catch (Exception e) {
			logger.error("Failure when init ProxyUtil", e);
			logger.error("choose NetworkInterface\n" + getNetworkInterface());
		}

	}

	public static boolean validateProxyAvailable(com.mantou.proxyservice.proxeservice.entity.Proxy p){

		HttpResult request = null;
		try {
			request = new HttpInvoker(keysourceurl).setproxy(p.getIp(), p.getPort()).request();
			if(request != null ){
				String key = new String(request.getResponseBody());
				if(key != null && key.contains("428174328")){
					return true;
				}
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
		} 

		return false;
	}

	public static boolean validateProxyConnect(HttpHost p) {
		if (localAddr == null) {
			logger.error("cannot get local ip");
			return false;
		}
		boolean isReachable = false;
		Socket socket = null;
		try {
			socket = new Socket();
			socket.bind(new InetSocketAddress(localAddr, 0));
			InetSocketAddress endpointSocketAddr = new InetSocketAddress(p.getAddress().getHostAddress(), p.getPort());
			socket.connect(endpointSocketAddr, 3000);
			logger.debug("SUCCESS - connection established! Local: " + localAddr.getHostAddress() + " remote: " + p);
			isReachable = true;
		} catch (Exception e) {
			logger.warn("FAILRE - CAN not connect! Local: " + localAddr.getHostAddress() + " remote: " + p);
		} finally {
			if (socket != null) {
				try {
					socket.close();
				} catch (IOException e) {
					logger.warn("Error occurred while closing socket of validating proxy", e);
				}
			}
		}
		return isReachable;
	}

	private static String getNetworkInterface() {
		String networkInterfaceName = "";
		Enumeration<NetworkInterface> enumeration = null;
		try {
			enumeration = NetworkInterface.getNetworkInterfaces();
		} catch (SocketException e1) {
			e1.printStackTrace();
		}
		while (enumeration.hasMoreElements()) {
			NetworkInterface networkInterface = enumeration.nextElement();
			networkInterfaceName += networkInterface.toString() + '\n';
			Enumeration<InetAddress> addr = networkInterface.getInetAddresses();
			while (addr.hasMoreElements()) {
				networkInterfaceName += "\tip:" + addr.nextElement().getHostAddress() + "\n";
			}
		}
		return networkInterfaceName;
	}
}
